package gmodel

import (
	"fmt"
	"github.com/buraksezer/consistent"
	"github.com/cespare/xxhash/v2"
)

//一致哈希算法的公用部分

// 哈希算法
type Hasher struct{}

func (h Hasher) Sum64(data []byte) uint64 {
	// you should use a proper hash function for uniformity.
	return xxhash.Sum64(data)
}

// 哈希环上的成员定义并实现consistent.Member接口
type HashRingMember string

func (m HashRingMember) String() string {
	return string(m)
}

// 自定义哈希环配置
/*
**对一致哈希算法库配置说明
cfg := consistent.Config{
		PartitionCount:    300,//最大切片数,就是把环切开后的最大分片数,memberNum不能大于这个值,否则报panic: not enough room to distribute partitions
		ReplicationFactor: 40,//虚拟节点,加强一致哈希分配的平衡性,相当于在环上分配了300*40=12000个节点
		Load:              1.25,
		Hasher:            global.Hasher{},
	}
*/
type ConsistentHashRingConfig struct {
	ConsistentConfig consistent.Config //致哈希算法库配置
	MemberNum        int               //实际在环上分配的成员数,该值不能大于PartitionCount
}

// 一致性哈希环初始化
// conf:哈希环配置 key:环上成员名称,初始化后实际成员名称为key_index,index = [1:membernum] 如:user_behavior_1
func NewConsistentHashRing(conf *ConsistentHashRingConfig, key string) *consistent.Consistent {
	ring := consistent.New(nil, conf.ConsistentConfig)
	for i := 0; i < conf.MemberNum; i++ {
		ring.Add(HashRingMember(fmt.Sprintf("%s_%d", key, i)))
	}
	return ring
}
